#include <iostream>
#include <map>
#include <queue>
#include "FileIO.h"
#include "cioMst.h"

using namespace std;
using CliExeHandle = int(*)(int argc, char* argv[]);

static int TxFileHandle(int argc, char **argv);
static int CioMstRxHandle(int argc, char **argv);

int main(int argc, char *argv[]) {
    const map<string, CliExeHandle> ExeTable = {
        {"TxFile", TxFileHandle},
        {"CioMstRx", CioMstRxHandle},
    };
    cout << "LibKz TEST FRAME >>> ";
    if (argc <= 1) {
        cout << "Input Para empty." << endl;
        return ERR_BADPARA;
    }
    const string cmdType = argv[1];
    auto cmdExePair = ExeTable.find(cmdType);
    if (cmdExePair != ExeTable.end()) {
        return cmdExePair->second(argc, argv);
    } else {
        cout << "Invalid cli cmd: " << cmdType << endl << "Supported cmd as follow:" << endl;
        for (const auto& o : ExeTable) {
            cout << o.first << endl;
        }
        return ERR_CMDNREG;
    }
}

static int TxFileHandle(int argc, char **argv)
{
    if (argc != 4) {
        cout << "TxFile para invalid: need 4 but given " << argc << endl;
        return ERR_BADPARA;
    }
    string portName = argv[2];
    string filePath = argv[3];
    return FileIO::TxCsvToCom(portName, filePath);
}

static int PutPkgQueue(queue<MstCioObj> q)
{
    if (q.empty()) {
        cout << "ERROR : return is empty" << endl;
        return ERR_FAILURE;
    }
    while (!q.empty()) {
        MstCioObj ret = q.front();
        cout << "recv pkg: " << ret.type << endl;
        PutRam(ret.data.data(), ret.data.size());
        cout << endl;
        q.pop();
    }
    return ERR_SUCCESS;
}

static int CioMstRxHandle(int argc, char **argv)
{
    /* Input Verify */
    if (argc != 3) {
        cout << "CioMstRxHandle para invalid: need 3 but given " << argc << endl;
        return ERR_BADPARA;
    }
    cout << endl;
    /* Input Data */
    string rxCaseFile = argv[2];
    vector<uint8_t> rxData;
    FileIO::ExtractCsv(rxCaseFile, rxData);
    /* Test API */
    queue<MstCioObj> q;
    cioMst mst("TJCFGMCP");
    mst.RxData(rxData, q);
    mst.RxData(rxData, q);
    mst.RxData(rxData, q);
    /* Verify result */
    PutPkgQueue(q);
    return ERR_SUCCESS;
}
